# -*- coding: utf-8 -*-
# @Author: Tim Liu
# @Date: 2024-05-06
# @Last Modified by: Tim Liu
# @Last Modified time: 2024-05-06

# @Description: api endpoints for api key verification

from fastapi import Security, Depends
from fastapi.security import APIKeyHeader, APIKeyQuery

from crewplus.apps.apikey.crud import AccountApiKeyDal
from crewplus.apps.apikey.models.account_api_key import AccountApiKey
#from apps.vadmin.auth.models import VadminUser, vadmin_auth_user_roles, VadminRole

from sqlalchemy.ext.asyncio import AsyncSession
from core.database import db_getter
from core.exception import CustomException
from utils import status

import logging
# 配置日志输出到标准输出
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

api_key_query = APIKeyQuery(name="api-key", auto_error=False)
api_key_header = APIKeyHeader(name="x-api-key", auto_error=False)

async def verify_api_key(db: AsyncSession, api_key: str):
    """
    验证api_key，这个方法 不能 使用asyncio.create_task方法的调用
    """
    logging.info("verify apikey")
    
    data: AccountApiKey = await AccountApiKeyDal(db).get_data(api_key=api_key)

    if data is None:
        raise CustomException("Invalid or missing API Key", code=status.HTTP_ERROR)
    
    return data

async def verify_api_key_value(api_key: str, auth_db: AsyncSession):
    """
    验证api key，这个方法 可以 用于asyncio.create_task方法的调用
    """
    logging.info("verify apikey count")
    api_key_count = await AccountApiKeyDal(auth_db).get_count(api_key=api_key)
    return api_key_count

async def get_api_key(
    api_key_query: str = Security(api_key_query),
    api_key_header: str = Security(api_key_header),
    db: AsyncSession = Depends(db_getter),
) -> AccountApiKey:
    """Retrieve and validate an API key from the query parameters or HTTP header.

    Args:
        api_key_query: The API key passed as a query parameter.
        api_key_header: The API key passed in the HTTP header.

    Returns:
        The API key passed from request.

    Raises:
        HTTPException: If the API key is invalid or missing.
    """
    api_key = None

    if api_key_query is not None:
        api_key = api_key_query
    
    if api_key_header is not None:
        api_key = api_key_header
    
    logging.info("get apikey from query or header: " + str(api_key))
    
    if api_key is None:
        raise CustomException("Invalid or missing API Key", code=status.HTTP_ERROR)
    
    apikey = await verify_api_key(db, api_key)
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
    
    return apikey
